Questions
10 of 13
1What role does Qdrant play in a typical RAG architecture, and what happens on either side of it in the pipeline?
2How would you design chunking and metadata so that retrieved chunks can be traced back to their source document and section for citation?
3A RAG system is returning chunks that are topically related but don't actually answer the user's question. How would you improve retrieval quality?
4How would you handle access control in a RAG system where different users are only permitted to retrieve chunks from documents they have permission to view?
5Why might you keep conversation-turn embeddings in a separate, short-lived collection rather than mixing them into your main document knowledge base?
6How would you model 'users who liked this also liked' recommendations using Qdrant's recommend/discovery query modes?
7How would you incorporate business signals like popularity or recency into a similarity-based recommendation without abandoning vector search entirely?
8What cold-start problem exists for a new item or new user in a vector-similarity recommendation system, and how might you mitigate it?
9How would you evaluate whether a change to your recommendation retrieval pipeline actually improved results, before rolling it out to all users?
10Design a Qdrant-backed search feature for a SaaS product with thousands of small customers, each with their own private dataset. What collection and sharding strategy would you use?
11One large enterprise tenant has 100x more data than a typical tenant in your shared multitenant collection. What problems could this cause, and how would you address them?
12How would you offer per-tenant usage metrics (storage, query volume) in a shared multitenant Qdrant deployment?
13What is the tradeoff of offering tenants a 'bring your own embedding model' option in a shared collection?
10 / 13

Design a Qdrant-backed search feature for a SaaS product with thousands of small customers, each with their own private dataset. What collection and sharding strategy would you use?

Shared collection with tenant_id discriminator and custom sharding by tenant

For thousands of small customers, the right design is a shared collection with a tenant_id discriminator payload field, custom sharding by tenant, and a payload index on tenant_id marked with is_tenant=True. Each tenant's data is identified by the tenant_id field, and every query includes a filter on that field. Custom sharding co-locates each tenant's data on a single shard, so a tenant-scoped query hits one shard instead of fanning out to all shards. This is the combination that balances isolation with operational simplicity: the data is logically isolated by the filter, the query is efficient because it is routed to a single shard, and the operational overhead is one collection and a small number of shards rather than one collection per tenant. The official Qdrant guidance explicitly recommends this pattern over one-collection-per-tenant because per-tenant collections do not scale past a few hundred and waste resources on the fixed overhead of each collection.

The mechanism that makes custom sharding work is that the shard key is chosen by the application, not hashed from the point ID. When you create a shard key for a tenant and upsert points with that shard key, Qdrant places all of those points on the shard associated with that key. A query that specifies the shard key is routed to that shard only, so the query does not fan out. This is the key to scaling to thousands of tenants: without custom sharding, every query would fan out to all shards, and the coordinator's merge cost would grow with the number of shards. With custom sharding, the query cost is bounded by the shard's size, not by the total number of tenants. The tenant_id field is also marked with is_tenant=True, which tells the optimizer that this field is used for tenant scoping and enables optimizations in the index and query planning. The combination of custom sharding (for routing) and is_tenant (for indexing) is the recommended multi-tenant pattern for current Qdrant versions.

  1. 1

    One shared collection, not one per tenant: scales to thousands of tenants without per-collection overhead.

  2. 2

    tenant_id payload field: identifies which tenant each point belongs to.

  3. 3

    Custom sharding by tenant: co-locates each tenant's data on a single shard.

  4. 4

    is_tenant=True: marks the tenant field for index and query optimization.

  5. 5

    Query with shard key: routes to one shard instead of fanning out.

  6. 6

    Query with tenant filter: enforces logical isolation in the application.

  7. 7

    Payload index on tenant_id: keyword index for efficient filtering.

  8. 8

    Trusted service: the query is issued by a service that knows the tenant, never by the client directly.

  9. 9

    Tiered multitenancy: large tenants can be moved to dedicated shards or collections.

The trade-off is between isolation and operational simplicity. A shared collection with filters provides logical isolation, which is sufficient for most SaaS products but not for tenants with strict physical-isolation requirements. Custom sharding improves query efficiency but requires the application to manage shard keys and to handle the case where a tenant grows large enough to warrant its own shard. The common mistake is to create one collection per tenant, which does not scale. The second mistake is to not use custom sharding, so every query fans out to all shards. The third mistake is to rely on the tenant filter alone without a payload index, which forces a scan on every query. The fourth mistake is to let clients query Qdrant directly, which means they could omit the tenant filter and see other tenants' data - the filter must be enforced by a trusted service. The fifth mistake is to not plan for a tenant that grows much larger than the others, which creates a hot shard. Version note: custom sharding and the is_tenant flag were added in recent Qdrant releases. If you are on an older version, the multi-tenant pattern may not have the same optimizations, and the practical threshold for the number of tenants in a shared collection may be lower.

javascript

Version-dependent: custom sharding (sharding_method=models.ShardingMethod.CUSTOM) and the is_tenant flag were added in recent Qdrant releases and have evolved. The exact API for creating shard keys, the supported key types (keyword vs integer), and the behavior when a shard key is not specified have changed. If you are on an older version, verify the multi-tenant support and benchmark the tenant-scoped query latency with your actual tenant distribution.

Difficulty: 9/10
Topics: Multitenancy, Sharding, SaaS Architecture

Scenario Questions

0-2 years experience
  1. 1

    You have 1000 small tenants and you are tempted to create one collection per tenant. Explain why a shared collection is better and how you would isolate their data.

  2. 2

    A teammate says custom sharding is unnecessary if you have a tenant filter. Explain the difference in query cost.

2-5 years experience
  1. 1

    You have 5000 tenants and some are much larger than others. Describe the tiering strategy that keeps the collection balanced.

  2. 2

    A tenant reports that their queries are slow. Diagnose whether the issue is the shard, the index, or the filter.

5-8 years experience
  1. 1

    Design the full architecture for a SaaS search feature with thousands of tenants, including the collection, the sharding, the access control, the ingestion, and the monitoring.

  2. 2

    You need to onboard a new enterprise tenant with 100M points into a collection that currently has 5000 small tenants. Describe the migration and the isolation.

8+ years experience
  1. 1

    You are designing a multi-tenant search platform that must serve 100,000 tenants with varying sizes, strict isolation, and per-tenant SLAs. Describe the architecture and the trade-offs.

  2. 2

    Derive the optimal shard count and tenant assignment as a function of the tenant size distribution, query rate, and latency SLO.

Follow-up Questions

  • How would you add a new tenant to the collection, and what would you do if the tenant's data is large enough that it should have its own shard?
  • How would you handle a tenant that needs strict physical isolation, which the shared collection cannot provide?